package com.iscale.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.google.gson.Gson;
import com.iscale.model.entity.BaseRegionInfo;
import com.iscale.mapper.BaseRegionInfoMapper;
import com.iscale.model.entity.QQDistrictResult;
import com.iscale.model.entity.SysUser;
import com.iscale.service.BaseRegionInfoService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.iscale.util.HttpUtil;
import com.iscale.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 区域信息 服务实现类
 * </p>
 *
 * @author Andychen
 * @since 2017-03-08
 */
@Service
public class BaseRegionInfoServiceImpl extends ServiceImpl<BaseRegionInfoMapper, BaseRegionInfo> implements BaseRegionInfoService {
    private static final Logger log = LoggerFactory.getLogger(BaseRegionInfoServiceImpl.class);

    @Autowired
    private RedisTemplate<String, List<BaseRegionInfo>> redisTemplate;


    @Override
    public long initRegionInfoByQQ() throws Exception {
        String url = "http://apis.map.qq.com/ws/district/v1/list?key=HRCBZ-WZV63-MII33-YPPMV-SMKEH-RIFCJ";
        String response = HttpUtil.get(url);
        if(StringUtil.isEmpty(response)){
            throw new Exception("获取区域信息API接口返回为空");
        }
        QQDistrictResult result = JSON.parseObject(response,QQDistrictResult.class);
        if (result.getStatus() != 0) {
            log.error(result.toString());
            throw new Exception("获取位置失败");
        }

        List<QQDistrictResult.ResultBean> provinces = result.getResult().get(0);

        List<QQDistrictResult.ResultBean> citys = result.getResult().get(1);

        List<QQDistrictResult.ResultBean> areas = result.getResult().get(2);

        List<BaseRegionInfo>  provinceList = new ArrayList<>();
        List<BaseRegionInfo>  cityList = new ArrayList<>();
        List<BaseRegionInfo>  areaList = new ArrayList<>();


        for (QQDistrictResult.ResultBean bean:provinces){
            //省
            provinceList.add(BaseRegionInfo.QQDistrictToBaseRegion(bean,0));
            if(null!=bean.getCidx()){
                serQQDistrictPid(citys,bean.getCidx().get(0),bean.getCidx().get(1),bean.getId());
            }
        }

        for (QQDistrictResult.ResultBean bean:citys){
            //市
            cityList.add(BaseRegionInfo.QQDistrictToBaseRegion(bean,1));
            if(null!=bean.getCidx()){
                serQQDistrictPid(areas,bean.getCidx().get(0),bean.getCidx().get(1),bean.getId());
            }
        }

        for (QQDistrictResult.ResultBean bean:areas){
            //区
            areaList.add(BaseRegionInfo.QQDistrictToBaseRegion(bean,2));
        }

        //批量保存或更新基础数据库
        provinceList.addAll(cityList);
        provinceList.addAll(areaList);

       insertOrUpdateBatch(provinceList);

       return provinceList.size();
    }

    @Override
    public List<BaseRegionInfo> getAllProvinces(){

        List<BaseRegionInfo> lists = redisTemplate.opsForValue().get("provinces-district");
        if (lists != null && lists.size()>0) {
            log.debug("从缓存中获取省数据");
            return lists;
        }
        //从数据查询
        EntityWrapper<BaseRegionInfo> entityWrapper = new EntityWrapper<>(new BaseRegionInfo());
        entityWrapper.isNull("pid").or("pid={0}",0);
        entityWrapper.orderBy("id",true);

        lists = selectList(entityWrapper);
        if (lists != null && lists.size()>0) {
            log.debug("从数据库中获取省数据");
            redisTemplate.opsForValue().set("provinces-district-", lists, 5, TimeUnit.DAYS);//放进缓存
            return lists;
        }
        return lists;
    }

    private void serQQDistrictPid( List<QQDistrictResult.ResultBean> list ,int start,int end,String pid){
        if(null!=list && list.size()>=start){
            if(list.size()<=end)end=list.size();
        }
        for (int i = start;i<=end;i++){
            list.get(i).setPid(pid);
        }
    }

    @Override
    public BaseRegionInfo getRegionById(String id){
        return selectById(id);
    }

    @Override
    public List<BaseRegionInfo> getSubRegionsById(String pid) throws Exception {
        List<BaseRegionInfo> lists = redisTemplate.opsForValue().get("subdistrict-" + pid);
        if (lists != null && lists.size()>0) {
            log.debug("从缓存中获取省市区数据");
            return lists;
        }
        //从数据查询
        EntityWrapper<BaseRegionInfo> entityWrapper = new EntityWrapper<>(new BaseRegionInfo());
        entityWrapper.where("pid={0}",pid);
        entityWrapper.orderBy("id",true);

        lists = selectList(entityWrapper);
        if (lists != null && lists.size()>0) {
            log.debug("从数据库中获取省市区数据");
            redisTemplate.opsForValue().set("subdistrict-" + pid, lists, 30, TimeUnit.DAYS);//放进缓存
            return lists;
        }
        //从腾讯地图 API查询
        String url = "http://apis.map.qq.com/ws/district/v1/getchildren?key=HRCBZ-WZV63-MII33-YPPMV-SMKEH-RIFCJ";
        if (StringUtils.hasText(pid)) {
            url = url  + "&id=" + pid;
        }
        String response = HttpUtil.get(url);
        if(StringUtil.isEmpty(response)){
            throw new Exception("获取区域信息API接口返回为空");
        }
        QQDistrictResult result = JSON.parseObject(response,QQDistrictResult.class);
        if (result.getStatus() != 0) {
            log.error(result.toString());
            throw new Exception("获取位置失败");
        }
        List<QQDistrictResult.ResultBean> subList = result.getResult().get(0);
        lists = new ArrayList<>();
        BaseRegionInfo paren = selectById(pid);
        int level = 4;
        if(null!=paren && null!=paren.getLevel())level=paren.getLevel()+1;
        for (QQDistrictResult.ResultBean bean:subList){
            bean.setPid(pid);
            lists.add(BaseRegionInfo.QQDistrictToBaseRegion(bean,level));
        }
        insertOrUpdateBatch(lists);
        redisTemplate.opsForValue().set("subdistrict-" + pid, lists, 30, TimeUnit.DAYS);//放进缓存
        return lists;
    }
}
